package com.davidlife.javase.objclasses;

import java.time.LocalDate;
import java.util.Objects;

/**
 * equals, hashCode, 和 toString 方法的总结例子，其中Manager类继承自Employee类：
 * 参考笔记：我的知识体系/javaSE/4-equals、hashCode、toString 方法总结
 * @author davidj
 *
 */
public class EqualsHashCodeToString {

	public static void main(String[] args) {
		
	}

}

class Employee {
	private String name;
	private double salary;
	private LocalDate hireDay;
	
	public Employee(String name, double salary, int year, int month, int day) {
		this.name = name;
		this.salary = salary;
		this.hireDay = LocalDate.of(year, month, day);
	}

	public String getName() {
		return name;
	}

	public double getSalary() {
		return salary;
	}

	public LocalDate getHireDay() {
		return hireDay;
	}

	public void raiseSalary(double byPercent) {
		double raise = salary * byPercent / 100;
		salary += raise;
	}
	
	@Override
	public boolean equals(Object otherObject) {
		// a quick test to see if the objects are identical
	      if (this == otherObject) return true;

	      // must return false if the explicit parameter is null
	      if (otherObject == null) return false;

	      // if the classes don't match, they can't be equal
	      if (getClass() != otherObject.getClass()) return false;
	      //这里因为在子类中覆盖了equals方法，即子类有自己相等的概念，所以这里不能用instanceof检测，只能用getClass。
	      //if(!(otherObject instanceof Employee)) return false;

	      // now we know otherObject is a non-null Employee
	      Employee other = (Employee) otherObject;

	      // test whether the fields have identical values
	      return Objects.equals(name, other.name) 
	    		  && salary == other.salary 
	    		  && Objects.equals(hireDay, other.hireDay);
	}
	
	@Override
	public int hashCode() {
		return Objects.hash(name, salary, hireDay);
	}
	
	@Override
	public String toString() {
		return getClass().getName() + "[name=" + name + ",salary=" + salary + ",hireDay=" + hireDay + "]";
	}
	
}

class Manager extends Employee {
	private double bonus;
	
	public Manager(String name, double salary, int year, int month, int day) {
		super(name, salary, year, month, day);
		bonus = 0;
	}
	
	public double getSalary() {
		double baseSalary = super.getSalary();
		return baseSalary + bonus;
	}

	public void setBonus(double bonus) {
		this.bonus = bonus;
	}
	
	public boolean equals(Object otherObject) {
		if (!super.equals(otherObject)) return false;
	      Manager other = (Manager) otherObject;
	      // super.equals checked that this and other belong to the same class
	      return bonus == other.bonus;
	}
	
	public int hashCode() {
		return java.util.Objects.hash(super.hashCode(), bonus);
	}

	public String toString() {
		return super.toString() + "[bonus=" + bonus + "]";
	}
}
